package gui.panel_new.evaluation.student;

import enums.TextBundleEnum;
import enums.URLEnum;
import gui.ClientTestFrame;
import gui.other.SendTestAction;
import j_util.Cronometer;
import j_util.Utiles;
import misc.BundlesProvider;
import model.eval.Test;
import net.Client;
import net.UserData;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ResourceBundle;
/*

    This file is part of Logica-Logike.

    Logica-Logike is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation version 3 of the License.

    Logica-Logike is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Logica-Logike.  If not, see <http://www.gnu.org/licenses/>.

 */
/**
 * @author Jose Martin Rozanec;
 */
public class TestOverviewStudentPanel extends JPanel {
    private JLabel namesLabel;
    private JLabel surnamesLabel;
    private JLabel studentsNumberLabel;
    private JLabel ipLabel;
    private JTextField namesField;
    private JTextField surnamesField;
    private JTextField studentsNumberField;
    private JTextField ipField;
    private JButton connectButton;

    private JLabel totalExcercisesLabel;
    private JLabel resolvedExcercisesLabel;
    private JButton finalizeButton;
    private JButton startTestButton;
    private JTextArea testArea;
    private JPanel connectionPanel;
    private JScrollPane testScrollPane;

    private Cronometer cronometer;

    private JPanel aboutPanel;
    private JTabbedPane tabbedPane;
    private JPanel exercisePanel;

    private ResourceBundle textBundle;
    private Client client;
    private Test test;

    private JLabel exerciseOverTotalLabel;
    private JPanel[] panels;

    public TestOverviewStudentPanel(Cronometer cronometer, JTabbedPane tabbedPane,
                                    JPanel exercisePanel, Test test, JLabel exerciseOverTotalLabel,
                                    JPanel[] panels) {
        this.cronometer = cronometer;
        this.exerciseOverTotalLabel = exerciseOverTotalLabel;
        this.panels = panels;
        initComponents();
        setButtonListeners();
        sizeButtons();
        layoutComponents();
        enableSidePanel(false);
        this.tabbedPane = tabbedPane;
        this.exercisePanel = exercisePanel;
        this.test = test;
    }

    private void initComponents() {
        textBundle = BundlesProvider.getBundle(URLEnum.TEXT_BUNDLE);
        namesLabel = new JLabel(textBundle.getString(TextBundleEnum.NAMES.toString()));
        surnamesLabel = new JLabel(textBundle.getString(TextBundleEnum.SURNAMES.toString()));
        studentsNumberLabel = new JLabel(textBundle.getString(TextBundleEnum.STUDENT_NUMBER.toString()));
        ipLabel = new JLabel(textBundle.getString(TextBundleEnum.IP.toString()));
        namesField = new JTextField(20);
        surnamesField = new JTextField(20);
        studentsNumberField = new JTextField(18);
        ipField = new JTextField(15);
        connectButton = new JButton(textBundle.getString(TextBundleEnum.CONNECT.toString()));

        totalExcercisesLabel = new JLabel(textBundle.getString(TextBundleEnum.TOTAL_EXCERCISES.toString()));
        resolvedExcercisesLabel = new JLabel(textBundle.getString(TextBundleEnum.EXCERCISES_RESOLVED.toString()));
        startTestButton = new JButton(textBundle.getString(TextBundleEnum.START.toString()));
        finalizeButton = new JButton(textBundle.getString(TextBundleEnum.FINALIZE_SEND.toString()));
        testArea = new JTextArea(28, 43);//28, 43);
        testArea.setEditable(false);
        testArea.setBackground(Color.WHITE);
        testArea.setBorder(null);
        testScrollPane = new JScrollPane(testArea);//todo ver como queda...
        testScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        testScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        testScrollPane.setBorder(BorderFactory.createTitledBorder(
                BorderFactory.createMatteBorder(1, 0, 0, 0, Color.BLACK),
                textBundle.getString(TextBundleEnum.TEST.toString())));
        connectionPanel = getConnectionPanel();
        connectionPanel.setBorder(BorderFactory.createTitledBorder(
                BorderFactory.createLineBorder(Color.BLACK),
                textBundle.getString(TextBundleEnum.CONNECTION.toString())));
    }

    private void layoutComponents() {
        setBackground(Color.WHITE);
        setLayout(new GridBagLayout());
        GridBagConstraints gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.insets = new Insets(5, 5, 5, 5);
        gridBagConstraints.gridheight = 4;
        gridBagConstraints.gridwidth = 2;
        add(connectionPanel, gridBagConstraints);
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridwidth = 1;
        add(getTestDataFinalizePanel(), gridBagConstraints);
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        add(testScrollPane, gridBagConstraints);
        gridBagConstraints.gridy = 8;
//        add(new JLabel(Utiles.createImageIcon("../../gui/images/connectAbout2.png")),gridBagConstraints);//todo ajustar!


    }

    private JPanel getTestDataFinalizePanel() {
        JPanel panel = new JPanel();
        GridLayout layout = new GridLayout(5, 1);
        layout.setVgap(3);
        panel.setLayout(layout);
        panel.setBackground(Color.WHITE);
        panel.add(totalExcercisesLabel);
        panel.add(resolvedExcercisesLabel);
        panel.add(new JLabel());//todo ver!!!
        panel.add(startTestButton);
        panel.add(finalizeButton);
        panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), ""));
        return panel;
    }

    private void setButtonListeners() {
        connectButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (checkUserData()) {
                    if (Utiles.checkIPFormat(ipField.getText())) {
                        client = new Client(ipField.getText());
                        if (client.isConnected()) {
                            enableConnectionPanel(false);
                            enableSidePanel(true);
                            finalizeButton.setEnabled(false);
                            client.setUserData(getUserData());
                            client.start();//la especificacion da a conocer que se puede invocar start() solo una vez;
                            //el cliente podria conectarse dos veces si cierra el programa y lo vuelve a abrir...
                            //La operacion se refleja en el servidor, de forma que no se pueda rehacer la evaluacion.
                            while (client.getTest() == null) {
                            }//wait until the test is sent...
//                            test = client.getTest();
                            exerciseOverTotalLabel.setText("" + test.getCurrentExerciseNumber() +
                                    "/" + client.getTest().getTotalExcercises());

                            copyTest(test, client.getTest());//todo creo que es inutil; revisar...
                            totalExcercisesLabel.setText(
                                    textBundle.getString(TextBundleEnum.TOTAL_EXCERCISES.toString()) + ": " +
                                            test.getTotalExcercises());
                        } else {
                            JOptionPane.showMessageDialog(TestOverviewStudentPanel.this,
                                    textBundle.getString(TextBundleEnum.WARNING_COULDNT_CONNECT.toString()),
                                    "", JOptionPane.WARNING_MESSAGE);
                        }
                    } else {
                        JOptionPane.showMessageDialog(TestOverviewStudentPanel.this,
                                textBundle.getString(TextBundleEnum.WARNING_INCORRECT_IP_FORMAT.toString()),
                                "", JOptionPane.WARNING_MESSAGE);
                    }
                } else {
                    JOptionPane.showMessageDialog(TestOverviewStudentPanel.this,
                            textBundle.getString(TextBundleEnum.WARNING_FILL_USER_DATA.toString()),
                            "", JOptionPane.WARNING_MESSAGE);
                }
            }
        });
        startTestButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                setCronometerTimeoutAction();
                cronometer.setRegressionTime(test.getMinutes());
                cronometer.start();
                Timer swingTimer = new Timer(test.getMinutes()*60*1000, new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                                BundlesProvider.getBundle(URLEnum.TEXT_BUNDLE).getString(TextBundleEnum.WARNING_TIMEOUT.toString()));
                    }
                });
                swingTimer.setRepeats(false);
                swingTimer.start();
                startTestButton.setEnabled(false);
                finalizeButton.setEnabled(true);
                if (tabbedPane.getTabCount() == 2) {
                    tabbedPane.removeTabAt(1);
                }
                tabbedPane.addTab(textBundle.getString(TextBundleEnum.EXCERCISE.toString()), null, exercisePanel);
                testArea.setText(test.getStudentSolutionString());
                testArea.setCaretPosition(0);
            }
        });
        finalizeButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ClientTestFrame.saveCurrentData(test.getCurrent().getPanelEnum(), panels);
                client.setResolvedTest(test);
                cronometer.reset();
                finalizeAction();
            }
        });
    }

    private void sizeButtons() {
        startTestButton.setPreferredSize(new Dimension(160, 25));
        finalizeButton.setPreferredSize(new Dimension(160, 25));
    }

    private JPanel getConnectionPanel() {
        JPanel panel = new JPanel();
        panel.setBackground(Color.WHITE);
        panel.setLayout(new GridBagLayout());
        GridBagConstraints gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.insets = new Insets(0, 2, 2, 3);
        gridBagConstraints.gridwidth = 3;
        panel.add(Utiles.getLabelFieldPanel(namesLabel, namesField), gridBagConstraints);
        gridBagConstraints.gridy = 1;
        panel.add(Utiles.getLabelFieldPanel(surnamesLabel, surnamesField), gridBagConstraints);
        gridBagConstraints.gridy = 2;
        panel.add(Utiles.getLabelFieldPanel(studentsNumberLabel, studentsNumberField), gridBagConstraints);
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 1;
        panel.add(ipLabel, gridBagConstraints);
        gridBagConstraints.gridx = 1;
        panel.add(ipField, gridBagConstraints);
        gridBagConstraints.gridx = 2;
        panel.add(connectButton, gridBagConstraints);
        return panel;
    }

    private void enableConnectionPanel(boolean enable) {
        namesField.setEnabled(enable);
        surnamesField.setEnabled(enable);
        studentsNumberField.setEnabled(enable);
        ipField.setEnabled(enable);
        connectButton.setEnabled(enable);
    }

    private void enableSidePanel(boolean enable) {
        startTestButton.setEnabled(enable);
        finalizeButton.setEnabled(enable);
    }

    private boolean checkUserData() {
        return !(namesField.getText().equals("") ||
                surnamesField.getText().equals("") ||
                studentsNumberField.getText().equals(""));
    }

    private UserData getUserData() {
        UserData data = new UserData();
        data.setNames(namesField.getText());
        data.setSurnames(surnamesField.getText());
        data.setStudentNumber(studentsNumberField.getText());
        return data;
    }

    public void auxSetConnectionValues() { //todo delete
        ipField.setText("127.0.0.1");
        studentsNumberField.setText("22051991");
        namesField.setText("Jose Martin");
        surnamesField.setText("Rozanec");
    }

    public Client getClient() {
        return client;
    }

    public void setClient(Client client) {
        this.client = client;
    }

    private void copyTest(Test reference, Test received) {
        reference.setExcercises(received.getExcercises());
        reference.setMinutes(received.getMinutes());
    }

    private void setCronometerTimeoutAction() {
        cronometer.setActionOnTimeout(new SendTestAction(client, test));
    }

    private void finalizeAction() {
        enableConnectionPanel(true);
        enableSidePanel(false);
        if (tabbedPane.getTabCount() == 2) {
            tabbedPane.removeTabAt(1);
        }
        testArea.setText("Su puntaje es de " + test.getAchievedScore() + " (" +
                (test.getAchievedPercentage() * 100) + "%)");//todo internacionalizar
    }

    public void refreshTestOverview() {
        testArea.setText(test.getStudentSolutionString());
        resolvedExcercisesLabel.setText(textBundle.getString(TextBundleEnum.EXCERCISES_RESOLVED.toString()) + ": " +
                test.getResolvedTestsPercentage() + "%");
        if (cronometer.hasTimedOut()) {
            finalizeAction();
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        TestOverviewStudentPanel panel = new TestOverviewStudentPanel(new Cronometer(),
                new JTabbedPane(), new JPanel(), new Test(), new JLabel(), new JPanel[1]);
        panel.auxSetConnectionValues();
        frame.setContentPane(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}
